/**
 * 历史数据相关路由
 */

const express = require('express');
const router = express.Router();
const mysql = require('../services/mysql');
const fetch = require('node-fetch');
const logger = require('../services/logger');

// 获取历史K线数据
router.get('/', async (req, res) => {
  try {
    const { symbol, interval, startTime, endTime, range } = req.query;
    
    // 添加更详细的请求参数日志
    logger.info(`历史数据查询开始 - 参数: symbol=${symbol}, interval=${interval}, startTime=${startTime}(${new Date(parseInt(startTime)).toISOString()}), endTime=${endTime}(${new Date(parseInt(endTime)).toISOString()}), range=${range}`);
    
    // 验证必需的参数
    if (!symbol || !interval || !startTime || !endTime) {
      logger.warn(`请求参数不完整: ${JSON.stringify(req.query)}`);
      return res.status(400).json({ 
        code: 400, 
        success: false,
        message: '缺少必需的参数',
        required: ['symbol', 'interval', 'startTime', 'endTime'] 
      });
    }
    
    // 判断时间范围是否在最近7天内或者请求的范围是今天、昨天或最近1周
    const sevenDaysAgo = Date.now() - (7 * 24 * 60 * 60 * 1000);
    const requestStartTime = parseInt(startTime);
    
    logger.info(`判断数据源 - 七天前时间戳: ${sevenDaysAgo}, 请求开始时间: ${requestStartTime}, 差值(天): ${(requestStartTime - sevenDaysAgo) / (24 * 60 * 60 * 1000)}`);
    
    if (requestStartTime >= sevenDaysAgo || range === '1w' || range === 'today' || range === 'yesterday') {
      logger.info(`决定从币安API获取数据 - range=${range}`);
      
      try {
        // 从币安API获取数据
        return await fetchFromBinance(req, res);
      } catch (error) {
        logger.error(`从币安API获取数据失败:`, error);
        logger.info(`尝试从数据库获取数据...`);
      }
    } else {
      logger.info(`决定从数据库获取数据 - range=${range}`);
    }
    
    // 否则从数据库获取数据
    logger.info(`开始从数据库获取数据`);
    
    // 获取数据库连接
    const connection = await mysql.getConnection();
    
    try {
      // 构建查询SQL
      const tableName = `kline_${interval}_enhanced`;
      
      // 验证表是否存在
      const [tables] = await connection.query(
        'SHOW TABLES LIKE ?',
        [tableName]
      );
      
      if (tables.length === 0) {
        logger.error(`表 ${tableName} 不存在`);
        return res.status(400).json({
          code: 400,
          success: false,
          message: `表 ${tableName} 不存在`,
          table: tableName
        });
      }
      
      const sql = `SELECT * FROM ${tableName} 
                   WHERE symbol = ? 
                   AND open_time >= ? 
                   AND open_time <= ? 
                   ORDER BY open_time ASC`;
                   
      logger.info(`执行数据库查询 - 表名: ${tableName}, SQL: ${sql}, 参数: [${symbol}, ${parseInt(startTime)}, ${parseInt(endTime)}]`);
      
      // 查询数据库
      const [rows] = await connection.query(
        sql,
        [symbol, parseInt(startTime), parseInt(endTime)]
      );
      
      logger.info(`数据库查询完成，查询到 ${rows.length} 条数据`);
      
      if (rows.length === 0) {
        logger.warn(`查询结果为空 - 可能的原因: 1.时间范围内无数据 2.表名错误 3.数据未导入`);
      }
      
      // 转换数据格式为币安API格式
      const data = rows.map(row => [
        row.open_time.toString(),
        row.open_price.toString(),
        row.high_price.toString(),
        row.low_price.toString(),
        row.close_price.toString(),
        row.volume.toString(),
        row.close_time.toString(),
        row.quote_volume.toString(),
        row.trades_count.toString(),
        row.taker_buy_volume.toString(),
        row.taker_buy_quote_volume.toString()
      ]);
      
      logger.info(`返回数据给客户端 - 共 ${data.length} 条数据`);
      res.json(data);
    } finally {
      connection.release();
      logger.info(`数据库连接已释放`);
    }
  } catch (error) {
    logger.error(`API错误:`, error);
    res.status(500).json({ 
      code: 500,
      success: false,
      message: 'API错误', 
      error: error.message || '未知错误'
    });
  }
});

// 从币安API获取K线数据
async function fetchFromBinance(req, res) {
  try {
    const { symbol, interval, startTime, endTime, range } = req.query;
    
    // 处理10m周期的特殊情况
    const actualInterval = interval === '10m' ? '5m' : interval;
    
    // 分段获取数据
    let allData = [];
    let currentStartTime = parseInt(startTime);
    const finalEndTime = parseInt(endTime);
    
    // 如果是今天的数据且当前时间很早，可能没有数据返回
    const isToday = range === 'today';
    
    while (currentStartTime < finalEndTime) {
      // 计算当前段的结束时间（每次最多获取1000根K线）
      // 5分钟 = 300000毫秒
      const segmentEndTime = Math.min(currentStartTime + (1000 * 300000), finalEndTime);
      
      // 构建币安API URL
      const binanceUrl = `https://api.binance.com/api/v3/klines?symbol=${symbol}&interval=${actualInterval}&startTime=${currentStartTime}&endTime=${segmentEndTime}&limit=1000`;
      logger.info(`请求币安API分段数据: ${binanceUrl}`);
      
      // 记录API请求开始时间
      const apiRequestStartTime = Date.now();
      
      const response = await fetch(binanceUrl);
      
      // 记录API响应时间
      const apiResponseTime = Date.now() - apiRequestStartTime;
      logger.info(`币安API响应时间: ${apiResponseTime}ms, 状态码: ${response.status}`);
      
      if (!response.ok) {
        logger.error(`币安API返回错误状态码: ${response.status}`);
        const errorText = await response.text();
        logger.error(`币安API错误响应内容: ${errorText}`);
        throw new Error(`币安API返回错误: ${response.status}, 响应: ${errorText}`);
      }
      
      const segmentData = await response.json();
      
      if (segmentData && segmentData.length > 0) {
        logger.info(`本段获取到 ${segmentData.length} 条5分钟K线数据，时间范围: ${new Date(parseInt(segmentData[0][0])).toISOString()} 至 ${new Date(parseInt(segmentData[segmentData.length-1][0])).toISOString()}`);
        allData = allData.concat(segmentData);
        
        // 更新开始时间为下一段
        currentStartTime = parseInt(segmentData[segmentData.length - 1][0]) + 300000; // 加5分钟
      } else {
        logger.info(`本段未获取到数据，API返回空数组`);
        break; // 如果没有数据了就退出循环
      }
      
      // 添加小延迟避免请求过快
      await new Promise(resolve => setTimeout(resolve, 100));
    }
    
    // 检查是否获取到了数据
    if (allData.length === 0) {
      logger.info(`未获取到任何数据，返回空数组`);
      return res.json([]);
    }
    
    logger.info(`总共获取到 ${allData.length} 条5分钟K线数据，时间范围: ${new Date(parseInt(allData[0][0])).toISOString()} 至 ${new Date(parseInt(allData[allData.length-1][0])).toISOString()}`);
    
    // 如果是10m周期，合并每两个5m周期
    if (interval === '10m') {
      logger.info(`开始合并5分钟K线为10分钟K线，原始数据长度: ${allData.length}`);
      const mergedData = [];
      let mergeFailCount = 0;
      for (let i = 0; i < allData.length - 1; i += 2) {
        if (i + 1 < allData.length) {
          const k1 = allData[i];
          const k2 = allData[i + 1];
          const timeDiff = parseInt(k2[0]) - parseInt(k1[0]);
          if (timeDiff === 5 * 60 * 1000) {
            mergedData.push([
              k1[0], // 使用第一根K线的开盘时间
              k1[1], // 使用第一根K线的开盘价
              Math.max(parseFloat(k1[2]), parseFloat(k2[2])).toString(), // 最高价取两者最高
              Math.min(parseFloat(k1[3]), parseFloat(k2[3])).toString(), // 最低价取两者最低
              k2[4], // 使用第二根K线的收盘价
              (parseFloat(k1[5]) + parseFloat(k2[5])).toString(), // 成交量相加
              k2[6], // 使用第二根K线的收盘时间
              (parseFloat(k1[7]) + parseFloat(k2[7])).toString(), // 成交额相加
              (parseInt(k1[8]) + parseInt(k2[8])).toString(), // 成交笔数相加
              (parseFloat(k1[9]) + parseFloat(k2[9])).toString(), // 主动买入成交量相加
              (parseFloat(k1[10]) + parseFloat(k2[10])).toString() // 主动买入成交额相加
            ]);
          } else {
            mergeFailCount++;
            logger.warn(`5分钟K线时间间隔异常，无法合并: ${new Date(parseInt(k1[0])).toISOString()} 至 ${new Date(parseInt(k2[0])).toISOString()}, 时间差: ${timeDiff / 60000}分钟`);
          }
        }
      }
      
      logger.info(`合并完成，得到 ${mergedData.length} 条10分钟K线数据，合并失败: ${mergeFailCount} 次`);
      return res.json(mergedData);
    } else {
      // 其他周期直接返回原始数据
      return res.json(allData);
    }
  } catch (error) {
    logger.error(`从币安API获取数据失败:`, error);
    return res.status(500).json({ 
      code: 500, 
      success: false,
      message: '从币安API获取数据失败', 
      error: error.message || '未知错误'
    });
  }
}

module.exports = router; 